// * Promise 对象的构造器语法如下：
// let promise1 = new Promise(function (resolve, reject) {})
// console.log(promise1) // Promise { <pending> }

// * 由 new Promise 构造器返回的 promise 对象具有以下内部属性：
// * state —— 最初是 "pending"，然后在 resolve 被调用时变为 "fulfilled"，或者在 reject 被调用时变为 "rejected"。
// * result —— 最初是 undefined，然后在 resolve(value) 被调用时变为 value，或者在 reject(error) 被调用时变为 error。

// **************************************************************************************************************************

// * 使用例子：
let promise2 = new Promise(function (resolve, reject) {
	// 当前 executor 函数会立即被调用
	console.log('executor')

	// 1s 后 reject 函数会被调用
	setTimeout(() => reject(new Error('出错了')), 1000)
})

// **************************************************************************************************************************

// * 只有一个结果或一个 error。
// * resolve / reject 只需要一个参数（或不包含任何参数），并且将忽略额外的参数。
let promise3 = new Promise(function (resolve, reject) {
	// * 因为只有第一次对 reject/resolve 的调用才会被处理。进一步的调用都会被忽略。
	resolve('done')

	console.log(1) // 1（会打印）
	reject(new Error('error')) // 被忽略
	setTimeout(() => resolve('ok')) // 被忽略
})

// **************************************************************************************************************************

// * executor 通常是异步执行某些操作，并在一段时间后调用 resolve/reject，但这不是必须的。我们还可以立即调用 resolve 或 reject。
// * Promise 对象的 state 和 result 属性都是内部的。我们无法直接访问它们。但我们可以对它们使用 .then/.catch/.finally 方法。

// * 【then】
let promise4 = new Promise(function (resolve, reject) {
	setTimeout(() => resolve('done'), 1000)
	// setTimeout(() => reject(new Error('error')), 1000)
})

// * .then 的第一个参数是一个函数，是接受的 resolve 的结果作为参数。
// * .then 的第二个参数是一个函数，是接受的 reject 的结果作为参数。
promise4.then(
	(result) => console.log(result), // done（1s后打印）
	(error) => console.log(error.message) // error（1s后打印）
)

// * 只对成功感兴趣，不提供第二个参数。
promise4.then((result) => console.log(result)) // done（1s后打印）

// * 只对失败感兴趣，第一个参数设置为null。
promise4.then(null, (error) => console.log(error.message)) // error（1s后打印）

// * 【catch】
// * 可以通过 .catch 直接捕获错误。它是 .then(null, f) 的完全的模拟，它是一个简写形式。
promise4
	.then(console.log) // done（1s后打印）
	.catch(console.log) // error（1s后打印）

// * 【finally】
// * .then 和 .catch 之后，还有一个 .finally 。它在 promise 完成或失败之后都会被调用（看放置的位置）。
// * .finally 处理程序也不应该返回任何内容。如果它返回了，返回的值会默认被忽略。
new Promise((resolve, reject) => {
	setTimeout(() => resolve('ok'), 1000)
})
	// .finally(() => console.log('finally')) // finally（放在上面先执行）
	.then((result) => console.log(result))
	.catch((error) => console.log(error.message))
	.finally(() => console.log('finally')) // finally（放在下面成功/失败回调后再执行）

// **************************************************************************************************************************
